package com.hxh.generater.springBoot.util;

import com.hxh.generater.springBoot.util.methodParse.ParseJavaMethod;
import com.hxh.generater.springBoot.util.methodParse.entity.JavaClassMethod;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.io.*;
import java.util.List;
import java.util.Map;

@Data
public class ProcessTemplate {

    //生成的临时模板文件1
    private File tempTemplateFile;
    //模板文件
    private String templatePah;
    private String additionPath;
    //替换词
    private Map<String, String> replaceWord;
    //生成文件路径
    private File classFile;

    private boolean returnModel;

    private final StringBuilder importAddition = new StringBuilder();
    private final StringBuilder autowiredAddition = new StringBuilder();

    /**
     * 生成模板 读取原始模板，写入临时文件
     *
     * @return 返回文件写入流
     */
    public static BufferedWriter step1(File tempTemplateFile, String templatePah) {
        try {
            FileWriter fileWriter = new FileWriter(tempTemplateFile);
            BufferedWriter writer = new BufferedWriter(fileWriter);

            File template = new File(templatePah);
            BufferedReader br = new BufferedReader(new FileReader(template));
            String line;

            while ((line = br.readLine()) != null) {
                if (StringUtils.isNotBlank(line)) {
                    writer.write(line);
                }
                writer.newLine();
            }
            br.close();
            return writer;
        } catch (Exception e) {
            throw new RuntimeException("生成模板 读取原始模板，写入临时文件 异常！", e);
        }
    }

    /**
     * 生成完整模板文件，替换词替换
     *
     * @param replaceWord      替换词
     * @param tempTemplateFile
     */
    public static File step2(File tempTemplateFile, Map<String, String> replaceWord) {
        try {
            String line;
            ProcessWriteLine processWriteLine = new ProcessWriteLine(replaceWord);
            String tempTemplatePath2 = tempTemplateFile.getAbsolutePath();
            tempTemplatePath2 = tempTemplatePath2 + ".2";
            File tempTemplate2 = new File(tempTemplatePath2);
            FileWriter fileWriter = new FileWriter(tempTemplate2);
            BufferedWriter writer = new BufferedWriter(fileWriter);
            BufferedReader br = new BufferedReader(new FileReader(tempTemplateFile));

            while ((line = br.readLine()) != null) {
                processWriteLine.writeLine(line, writer);
            }
            br.close();
            writer.flush();
            fileWriter.close();
            return tempTemplate2;
        } catch (Exception e) {
            throw new RuntimeException("生成完整模板文件，替换词替换 异常！", e);
        }

    }

    /**
     * 处理重复的方法 - 生成最终文件
     *
     * @param tempTemplate2
     * @param classFile
     * @param replaceWord
     * @param returnModel
     */
    public static String step3(File tempTemplate2, File classFile, Map<String, String> replaceWord, boolean returnModel) {
        try {
            StringWriter stringWriter = null;
            FileWriter fileWriter = null;
            BufferedWriter writer = null;
            if (returnModel) {
                stringWriter = new StringWriter();
                writer = new BufferedWriter(stringWriter);
            } else {
                fileWriter = new FileWriter(classFile);
                writer = new BufferedWriter(fileWriter);
            }

            List<JavaClassMethod> methodList = ParseJavaMethod.parser(tempTemplate2.getAbsolutePath());
            List<JavaClassMethod> methodRepeatList = ParseJavaMethod.tagRepeatMethod(methodList);
            ProcessWriteLine processWriteLine = new ProcessWriteLine(replaceWord, methodList, methodRepeatList);
            BufferedReader br = new BufferedReader(new FileReader(tempTemplate2));

            String line;
            int currentLine = 0;
            while ((line = br.readLine()) != null) {
                currentLine++;
                processWriteLine.writeLineWithRepeatMethod(line, writer, currentLine);
            }
            br.close();
            writer.flush();
            writer.close();
            if (fileWriter != null) {
                fileWriter.close();
            }
            if (returnModel) {
                return stringWriter.toString();
            }
        } catch (Exception e) {
            throw new RuntimeException("处理重复的方法 - 生成最终文件 异常！", e);
        }
        return null;
    }

    /**
     * 删除临时文件
     *
     * @param tempTemplateFile
     * @param tempTemplate2
     */
    public static void deleteTempFile(File tempTemplateFile, File tempTemplate2) {
        String bakPath = tempTemplateFile.getAbsolutePath() + ".bak";
        String bakPath2 = tempTemplate2.getAbsolutePath() + ".bak";
        File bakFile = new File(bakPath);
        File bakFile2 = new File(bakPath2);
        if (tempTemplateFile.exists()) {
            tempTemplateFile.delete();
        }
        if (tempTemplate2.exists()) {
            tempTemplate2.delete();
        }
        if (bakFile.exists()) {
            bakFile.delete();
        }
        if (bakFile2.exists()) {
            bakFile2.delete();
        }
    }

    public String process() {
        //读取模板文件
        BufferedWriter writer = step1(tempTemplateFile, templatePah);
        //处理自定义添加的代码
        processAddition(writer, additionPath, importAddition, autowiredAddition);
        //模板文件生成完毕 开始统一替换
        replaceWord.put("importAddition", importAddition.toString());
        replaceWord.put("autowiredAddition", autowiredAddition.toString());
        //生成完整模板文件，替换词替换
        File tempTemplate2 = step2(tempTemplateFile, replaceWord);
        //替换完毕，开始处理重复方法 - 生成最终文件
        String result = step3(tempTemplate2, classFile, replaceWord, returnModel);
        deleteTempFile(tempTemplateFile, tempTemplate2);

        return result;
    }

    /**
     * 处理自定义添加的代码  这里关闭、flush writer
     *
     * @param writer
     * @throws IOException
     */
    public static void processAddition(BufferedWriter writer, String additionPath, StringBuilder importAddition, StringBuilder autowiredAddition) {
        try {
            BufferedReader br;
            String line;
            File additionFile = new File(additionPath);
            if (additionFile.exists() && additionFile.isDirectory()) {
                File[] additionFiles = additionFile.listFiles();
                if (additionFiles != null) {
                    for (File file : additionFiles) {
                        br = new BufferedReader(new FileReader(file));
                        while ((line = br.readLine()) != null) {
                            ProcessWriteLine.processPerLine(line, importAddition, autowiredAddition, writer);
                        }
                        br.close();
                    }
                }
            }
            writer.newLine();
            writer.write("}");
            writer.flush();
            writer.close();
        } catch (Exception e) {
            throw new RuntimeException("处理自定义添加的代码 异常！", e);
        }

    }

    public static void processAdditionFile(BufferedWriter writer, String additionFilePath, StringBuilder importAddition, StringBuilder autowiredAddition) {
        try {
            BufferedReader br;
            String line;
            File additionFile = new File(additionFilePath);
            if (additionFile.exists() && additionFile.isFile()) {
                br = new BufferedReader(new FileReader(additionFile));
                while ((line = br.readLine()) != null) {
                    ProcessWriteLine.processPerLine(line, importAddition, autowiredAddition, writer);
                }
                br.close();
            }
            writer.newLine();
        } catch (Exception e) {
            throw new RuntimeException("处理自定义添加的代码 异常！", e);
        }

    }
}
